package cn.mw.cmdb.controller;

import cn.mw.cmdb.config.MQTT.MessageArrivedByV6800;
import cn.mw.cmdb.config.MQTTProviderConfig;
import cn.mw.cmdb.entity.*;
import cn.mw.cmdb.entity.cloudWisdom.CloudWisdomInstanceReportHistoryInfo;
import cn.mw.cmdb.entity.cloudWisdom.CloudWisdomReportHistoryInfo;
import cn.mw.cmdb.enums.OperatorTypeDescEnum;
import cn.mw.cmdb.param.*;
import cn.mw.cmdb.service.InstanceImportHistoryService;
import cn.mw.cmdb.service.ServiceAction;
import cn.mw.cmdb.service.impl.*;
import cn.mw.cmdb.view.ViewManager;
import cn.mw.components.mongodb.entity.SearchParam;
import cn.mw.log.client.LogClientSimple;
import cn.mw.log.enums.BusinessLogType;
import cn.mw.log.enums.LogLevel;
import cn.mw.microMonitorCommon.api.common.BaseApiService;
import cn.mw.microMonitorCommon.api.common.ResponseBase;
import cn.mw.microMonitorCommon.constant.Constants;
import cn.mw.microMonitorCommon.entity.cmdb.ModelExportDataInfoListParam;
import cn.mw.microMonitorCommon.entity.cmdb.ModelExportDataInfoParam;
import cn.mw.microMonitorCommon.entity.common.MwModuleInfoDto;
import cn.mw.microMonitorCommon.security.utils.SecurityUtils;
import cn.mw.microMonitorCommon.util.DateUtils;
import cn.mw.microMonitorCommon.util.SpringUtils;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.util.List;
import java.util.Map;

import static cn.mw.cmdb.enums.ModelConfigKeyEnum.systemDevType;
import static cn.mw.cmdb.enums.PageDescEnum.Modelinstance;
import static cn.mw.cmdb.util.ValConvertUtil.booleanValueConvert;

@RequestMapping("/modelView")
@Controller
@Tag(name = "资产视图")
@Slf4j
public class InstanceViewController extends BaseApiService {
    private CmdbServiceManage cmdbServiceManage;
    private ViewManager viewManager;
    private MessageSource messageSource;
    @Autowired
    private MQTTProviderConfig mqttProviderConfig;
    private LogClientSimple logClientSimple;
    private InstanceImportHistoryService instanceImportHistoryService;

    public InstanceViewController(CmdbServiceManage cmdbServiceManage, ViewManager viewManager
            , MessageSource messageSource, LogClientSimple logClientSimple, InstanceImportHistoryService instanceImportHistoryService) {
        this.cmdbServiceManage = cmdbServiceManage;
        this.viewManager = viewManager;
        this.messageSource = messageSource;
        this.logClientSimple = logClientSimple;
        this.instanceImportHistoryService = instanceImportHistoryService;
    }


    @PostMapping("/batchEditorInstance")
    @ResponseBody
    @PreAuthorize("@mwAuthorizationCheck.check('291')")
    @Operation(summary = "批量修改实例")
    public ResponseBase batchEditorInstance(@RequestBody BatchEditorViewInstance param) throws Exception {
        cmdbServiceManage.service(param, ServiceAction.batchUpd);
        return setResultSuccess(messageSource.getMessage("upd-success", null, LocaleContextHolder.getLocale()));
    }

    @PostMapping("/saveFieldSetting")
    @ResponseBody
    @Operation(summary = "保存字段设置")
    public ResponseBase saveFieldSetting(@RequestBody TableHeader param) throws Exception {
        cmdbServiceManage.service(param, ServiceAction.add);
        return setResultSuccess(messageSource.getMessage("add-success", null, LocaleContextHolder.getLocale()));
    }

    @PostMapping("/editorFieldSetting")
    @ResponseBody
    @Operation(summary = "修改字段设置")
    public ResponseBase editorFieldSetting(@RequestBody TableHeader param) throws Exception {
        cmdbServiceManage.service(param, ServiceAction.update);
        return setResultSuccess(messageSource.getMessage("upd-success", null, LocaleContextHolder.getLocale()));
    }

    @PostMapping("/recoverFieldSetting")
    @ResponseBody
    @Operation(summary = "重置字段设置")
    public ResponseBase recoverFieldSetting(@RequestBody TableHeader param) throws Exception {
        cmdbServiceManage.service(param, ServiceAction.remove);
        return setResultSuccess(messageSource.getMessage("upd-success", null, LocaleContextHolder.getLocale()));
    }

    @PostMapping(value = "/import/getFieldByFile")
    @ResponseBody
    @PreAuthorize("@mwAuthorizationCheck.check('294')")
    @Operation(summary = "获取上传文件的表头字段")
    public ResponseBase getFieldByFile(MultipartHttpServletRequest request) throws Exception {
        MultipartFile file = request.getFile("file");
        String json = request.getParameter("importParam");
        ModelExportDataInfoParam param = JSONObject.parseObject(json, ModelExportDataInfoParam.class);
        InstanceViewImpl service = (InstanceViewImpl) cmdbServiceManage.getModelService(InstanceViewImpl.ID);
        ModelExportPropertyParam fieldByFile = service.getFieldByFile(file, param);
        return setResultSuccess(fieldByFile);
    }

    @PostMapping("/import/importDataInfo")
    @ResponseBody
    @Operation(summary = "上传文件数据导入")
    public ResponseBase importDataInfo(MultipartHttpServletRequest request) throws Exception {
        MultipartFile file = request.getFile("file");
        String json = request.getParameter("importParam");
        ModelExportDataInfoListParam param = JSONObject.parseObject(json, ModelExportDataInfoListParam.class);
        InstanceViewImpl service = (InstanceViewImpl) cmdbServiceManage.getModelService(InstanceViewImpl.ID);
        InstanceImportHistoryInfo resultParam = service.importInsertDataInfo(file, param);
        String nickName = SecurityUtils.getUser().getNickName();
        logClientSimple.addBusinessLog(LogLevel.INFO.getId(), BusinessLogType.CMDB_MANAGE.getId(),
                messageSource.getMessage("mwCmdb-operation-log", new Object[]{nickName, DateUtils.now()
                        , BusinessLogType.CMDB_MANAGE.getCnName(), OperatorTypeDescEnum.batchImport.getCname() + Modelinstance.getDesc(),
                        OperatorTypeDescEnum.batchImport.getCname(),
                        StringUtils.equals(Constants.OperationStatus.FAILED, resultParam.getOperateResult())
                                ? Constants.OperationStatus.FAILED : Constants.OperationStatus.SUCCESS}, LocaleContextHolder.getLocale()));
        return setResultSuccess(resultParam);
    }

    @PostMapping("getInstanceImportHistoryInfoByPage")
    @ResponseBody
    @ApiOperation(value = "分页查询导入导出历史记录")
    public ResponseBase<IPage<CloudWisdomReportHistoryInfo>> getInstanceImportHistoryInfoByPage(@RequestBody SearchParam param) throws Exception {
        return setResultSuccess(instanceImportHistoryService.getInstanceImportHistoryInfoByPage(param));
    }

    @PostMapping("getInstanceImportDetailByPage")
    @ResponseBody
    @ApiOperation(value = "分页查询导入详情")
    public ResponseBase<IPage<CloudWisdomInstanceReportHistoryInfo>> getInstanceImportDetailByPage(@RequestBody SearchParam param) throws Exception {
        return setResultSuccess(instanceImportHistoryService.getInstanceImportDetailByPage(param));
    }

    @Operation(summary = "资产导入结果导出")
    @PostMapping("/exportInstanceImportDetail")
    @PreAuthorize("@mwAuthorizationCheck.check('296')")
    public void exportInstanceImportDetail(@RequestBody SearchParam param, HttpServletRequest request, HttpServletResponse response) throws Exception {
        instanceImportHistoryService.exportExcelImportResult(param, request, response);
    }

    @PostMapping("getInstanceImportHistoryInfoStatusCount")
    @ResponseBody
    @ApiOperation(value = "导入导出历史按状态统计")
    public ResponseBase<Map<String, Integer>> getInstanceImportHistoryInfoStatusCount(@RequestBody SearchParam param) throws Exception {
        return setResultSuccess(instanceImportHistoryService.getInstanceImportHistoryInfoStatusCount(param));
    }


    @PostMapping("/export/exportInstanceList")
    @ResponseBody
    @PreAuthorize("@mwAuthorizationCheck.check('295')")
    @Operation(summary = "导出资产列表数据")
    public ResponseBase exportInstanceList(@RequestBody ExportInstanceParam param, HttpServletResponse response) throws Exception {
        InstanceViewImpl service = (InstanceViewImpl) cmdbServiceManage.getModelService(InstanceViewImpl.ID);
        int num = service.exportInstanceList(param, response);
        String nickName = SecurityUtils.getUser().getNickName();
        logClientSimple.addBusinessLog(LogLevel.INFO.getId(), BusinessLogType.CMDB_MANAGE.getId(),
                messageSource.getMessage("mwCmdb-operation-log", new Object[]{nickName, DateUtils.now()
                        , BusinessLogType.CMDB_MANAGE.getCnName(), OperatorTypeDescEnum.batchExport.getCname() + Modelinstance.getDesc(),
                        OperatorTypeDescEnum.batchExport.getCname() + num + "条资产数据", Constants.OperationStatus.SUCCESS}, LocaleContextHolder.getLocale()));

        return setResultSuccess();
    }

    @PostMapping("/upload/cmdbUploadFile")
    @ResponseBody
    @Operation(summary = "资产上传文件")
    public ResponseBase cmdbUploadFile(@RequestBody MultipartFile file) throws Exception {
        InstanceViewImpl service = (InstanceViewImpl) cmdbServiceManage.getModelService(InstanceViewImpl.ID);
        List fileName = service.cmdbUploadFile(file);
        return setResultSuccess(fileName);
    }


    @PostMapping("/export/exportModelTemplate")
    @ResponseBody
    @PreAuthorize("@mwAuthorizationCheck.check('293')")
    @Operation(summary = "资产导入模板导出")
    public ResponseBase exportModelInstanceTemplate(@RequestBody ExportInstanceTemplate param, HttpServletResponse response) throws Exception {
        InstanceViewImpl service = (InstanceViewImpl) cmdbServiceManage.getModelService(InstanceViewImpl.ID);
        service.exportModelInstanceTemplate(param, response);
        String nickName = SecurityUtils.getUser().getNickName();
        logClientSimple.addBusinessLog(LogLevel.INFO.getId(), BusinessLogType.CMDB_MANAGE.getId(),
                messageSource.getMessage("mwCmdb-operation-log", new Object[]{nickName, DateUtils.now()
                        , BusinessLogType.CMDB_MANAGE.getCnName(), Modelinstance.getDesc() + OperatorTypeDescEnum.exportTemplate.getCname(),
                        Modelinstance.getDesc() + OperatorTypeDescEnum.exportTemplate.getCname(), Constants.OperationStatus.SUCCESS}, LocaleContextHolder.getLocale()));

        return setResultSuccess();
    }


    @PostMapping("/getSelectDataByRelation")
    @ResponseBody
    @Operation(summary = "获取外部关联下拉数据")
    public ResponseBase getSelectDataByRelation(@RequestBody PropertyRelationInfo relationPropertyInfo) throws Exception {
        InstanceViewImpl service = (InstanceViewImpl) cmdbServiceManage.getModelService(InstanceViewImpl.ID);
        List<MwRelationInstanceParam> selectDataByRelation = service.getSelectDataByRelation(relationPropertyInfo);
        return setResultSuccess(selectDataByRelation);
    }

    /**
     * 资产视图列表可显示的全部字段
     *
     * @return
     * @throws Exception
     */
    @PostMapping("/allShowFields")
    @ResponseBody
    @Operation(summary = "资产视图列表可显示的全部字段")
    public ResponseBase allShowFields() throws Exception {
        //TODO 获取所有enableShow为true且权限为List的，在获取defaultListVisible，true表示默认勾选，false表示默认不勾选
        InstanceViewImpl viewService = (InstanceViewImpl) cmdbServiceManage.getModelService(InstanceViewImpl.ID);
//        viewService.testRelationSync();
        return setResultSuccess();
    }

    /**
     * 整合机房布局数据
     *
     * @return
     * @throws Exception
     */
    @PostMapping("/getRoomLayoutIntegration")
    @ResponseBody
    @Operation(summary = "整合机房布局数据")
    public ResponseBase getRoomLayoutIntegration(@RequestBody InstanceParam param) throws Exception {
        InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        List<MwRoomLayoutIntegration> roomLayoutIntegration = instanceService.getRoomLayoutIntegration(param.getIds());
        return setResultSuccess(roomLayoutIntegration);
    }

    /**
     * 整合机房布局数据
     *
     * @return
     * @throws Exception
     */
    @PostMapping("/getCabinetLayoutIntegration")
    @ResponseBody
    @Operation(summary = "整合机柜布局数据")
    public ResponseBase getCabinetLayoutIntegration(@RequestBody InstanceParam param) throws Exception {
        InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        List<MwCabinetLayoutIntegration> cabinetLayoutIntegration = instanceService.getCabinetLayoutIntegration(param.getIds());
        return setResultSuccess(cabinetLayoutIntegration);
    }

    /**
     * 资产视图列表可显示的全部字段
     *
     * @return
     * @throws Exception
     */
    @PostMapping("/batchUploadQrCodeLabel")
    @ResponseBody
    @Operation(summary = "批量下载二维码标签")
    public ResponseBase batchUploadQrCodeLabel(@RequestBody TableSearchParam param, HttpServletResponse response) throws Exception {
        InstanceViewImpl viewService = (InstanceViewImpl) cmdbServiceManage.getModelService(InstanceViewImpl.ID);
        viewService.batchUploadQrCodeLabel(param, response);
        return setResultSuccess();
    }

    @PostMapping("/createAssetCode")
    @ResponseBody
    @Operation(summary = "自动生成资产编码")
    public ResponseBase createAssetCode(@RequestBody InstanceParam param) throws Exception {
        InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        String s = instanceService.getAssetsCodeCacheStr(param.getModelId());
        return setResultSuccess(s);
    }

    @PostMapping("/resetAssetCode")
    @ResponseBody
    @Operation(summary = "回收资产编码")
    public ResponseBase resetAssetCode(@RequestBody IdListsParam param) throws Exception {
        InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
//        instanceService.insertAssetsCodeCacheList(param.getLists());
        return setResultSuccess();
    }

    @PostMapping("/getDefaultSystemDev")
    @ResponseBody
    @Operation(summary = "获取当前系统运行客户环境")
    public ResponseBase getDefaultSystemDev() throws Exception {
        MwCMDBConfigImpl configServer = (MwCMDBConfigImpl) cmdbServiceManage.getModelService(MwCMDBConfigImpl.ID);
        MwCMDBConfigInfo cmdbConfigInfo = configServer.doSelectByKey(systemDevType.name());
        Object configValue = cmdbConfigInfo.getConfigValue();
        String systemType = "";
        if (configValue instanceof String) {
            systemType = (String) configValue;
        }
        return setResultSuccess(systemType);
    }

    @PostMapping("/selectAlertInfosByRoomId")
    @ResponseBody
    @Operation(summary = "根据机房Id获取所有实例告警信息")
    public ResponseBase selectAlertInfosByRoomId(@RequestBody InstanceParam param) throws Exception {
        InstanceViewImpl viewService = (InstanceViewImpl) cmdbServiceManage.getModelService(InstanceViewImpl.ID);
        List<AlertInstanceInfoParam> instanceAlertList = viewService.getInstanceAlertList(param.getId());
        return setResultSuccess(instanceAlertList);
    }

    @PostMapping("/rollBackInstanceDataByImport")
    @ResponseBody
    @PreAuthorize("@mwAuthorizationCheck.check('297')")
    @Operation(summary = "导入资产数据回滚接口")
    public ResponseBase rollBackInstanceDataByImport(@RequestBody RollBackInstanceImportInfo param) throws Exception {
        InstanceViewImpl viewService = (InstanceViewImpl) cmdbServiceManage.getModelService(InstanceViewImpl.ID);
        viewService.rollBackInstanceDataByImport(param);
        return setResultSuccess();
    }

    @PostMapping("/getTrunkMonitorFlag")
    @ResponseBody
    @Operation(summary = "获取是否Trunk监控")
    public ResponseBase getTrunkMonitorFlag() throws Exception {
        String systemInterfaceConfigKey = "system.trunkMonitorFlag.configKey";
        boolean trunkMonitorFlag = booleanValueConvert(SpringUtils.getPropertiesValue(systemInterfaceConfigKey));
        return setResultSuccess(trunkMonitorFlag);
    }


    @PostMapping("/test/subScribeMATT")
    @ResponseBody
    @Operation(summary = "mqtt订阅主题")
    public ResponseBase subScribeMATT(@RequestBody MQTTParamInfo param) throws Exception {
//        InstanceViewImpl viewService = (InstanceViewImpl) cmdbServiceManage.getModelService(InstanceViewImpl.ID);
        String[] topic = {"V6800Upload/#", param.getTopic()};
        int[] Qos = {1, 1};
        mqttProviderConfig.subScribe(topic, Qos);
        return setResultSuccess();
    }

    @PostMapping("/test/publishMQTT")
    @ResponseBody
    @Operation(summary = "mqtt发布消息")
    public ResponseBase publishMATT(@RequestBody MQTTParamInfo param) throws Exception {
//        InstanceViewImpl viewService = (InstanceViewImpl) cmdbServiceManage.getModelService(InstanceViewImpl.ID);
//        viewService.exportTest(param);
        String topic = param.getTopic();
        String message = param.getMessage();
        mqttProviderConfig.publish(topic, message);
        return setResultSuccess();
    }

    @PostMapping("/test/testMethod")
    @ResponseBody
    @Operation(summary = "测试方法")
    public ResponseBase testMethod(@RequestBody MQTTParamInfo param) throws Exception {
//        InstanceViewImpl viewService = (InstanceViewImpl) cmdbServiceManage.getModelService(InstanceViewImpl.ID);
//        String[] topic = {"V6800Upload.0305090086.Init", param.getTopic()};
//        int[] Qos = {1, 1};
//        mqttProviderConfig.subScribe(topic, Qos);
//        return setResultSuccess();
        MwCmdbFieldApiImpl bean = SpringUtils.getBean(MwCmdbFieldApiImpl.class);
        List<MwModuleInfoDto> abutmentModuleFiledInfo = bean.getAbutmentModuleFiledInfo();
//        MessageArrivedByV5008 v5008 = new MessageArrivedByV5008();
//        v5008.deviceUNumCheck(param.getTopic(), param.getMessage());
        return setResultSuccess(abutmentModuleFiledInfo);

    }

    @PostMapping("/test/testMethod2")
    @ResponseBody
    @Operation(summary = "测试方法")
    public ResponseBase testMethod2(@RequestBody MQTTParamInfo param) throws Exception {
        MessageArrivedByV6800 v6800 = new MessageArrivedByV6800();
        v6800.heartBeatStateSync(param.getMessage());
        return setResultSuccess();
    }

}
